package etnorservice.etnor_service.aop.aspect;

import etnorservice.etnor_service.aop.annoution.OperationLog;
import etnorservice.etnor_service.domain.po.OperationLogEntity;
import etnorservice.etnor_service.mapper.OperationLogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * AOP切面，用于拦截带有@OperationLog注解的方法，并记录操作日志
 */
@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private OperationLogMapper operationLogMapper;

    @Around("@annotation(operationLog)")
    public Object logOperation(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
        long startTime = System.currentTimeMillis();
        String methodName = joinPoint.getSignature().getName();
        String requestParams = Arrays.toString(joinPoint.getArgs());

        Object result = null;
        String exceptionMessage = null;

        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            exceptionMessage = e.getMessage();
        } finally {
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;
            long responseTime = endTime; // 这里假设响应时间就是方法结束的时间

            OperationLogEntity logEntity = new OperationLogEntity();
            logEntity.setMethodName(methodName);
            logEntity.setRequestParams(requestParams);
            logEntity.setResponseResult(result != null ? result.toString() : null);
            logEntity.setResponseTime(responseTime);
            logEntity.setExecutionTime(executionTime);
            logEntity.setException(exceptionMessage); // 设置异常信息

            operationLogMapper.insertOperationLog(logEntity);
        }

        if (exceptionMessage != null) {
            throw new RuntimeException(exceptionMessage); // 重新抛出异常，以便调用者能够处理
        }

        return result;
    }
}
